<?php

namespace App\Http\Controllers\Attendance;

use App\Http\Controllers\Controller;
use App\Models\Personnel\PersonnelCleaner;
use Illuminate\Database\Query\Builder;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class AttendanceReportController extends Controller
{
    public function getReportData(Request $request)
    {
        $params = $request->all();
        $month = $params['month'] ? date('Y-m', strtotime($params['month'])) : date('Y-m');
        $params['endDate'] = date('Y-m-25', strtotime($month));
        $params['startDate'] = date('Y-m-26', strtotime($month.'- 1 month'));

        $data = $this->getAttendanceData($params)->orderBy('line', 'asc')->get()->toArray();

        $data = $this->transData($data, $params);

        return response()->formatJson($data);
    }

    public function getAttendanceData($params): Builder
    {
        $cleaner = PersonnelCleaner::query()->get()->pluck('name')->toArray();
        // 这里使用 DB 查询，可以改善性能
        $query = DB::table('akbus_attendance')
            ->select(DB::raw('date(actual_sign_time) as actual_sign_date, id, driver, license_plate_num, line, actual_sign_time'))
            ->whereBetween('actual_sign_time', [$params['startDate'], $params['endDate']])
            ->whereNotIn('driver', $cleaner);

        if (isset($params['license_plate_num'])) {
            $query->where('license_plate_num', 'like', '%'.$params['license_plate_num'].'%');
        }

        return $query;
    }

    public function transData($data, $params)
    {
        $dateList = getListFromDateRange($params['startDate'], $params['endDate']);
        $data = collect($data)->groupBy('license_plate_num');
        $busDriver = [];
        $postData = [];
        foreach ($data as $licensePlateNum => $item) {
            $dates = $item->groupBy('actual_sign_date')->toArray();
            // 填充无日期
            foreach ($dateList as $d) {
                if (! array_key_exists($d, $dates)) {
                    $dates[$d] = [];
                }
            }
            ksort($dates);
            foreach ($dates as $k => $date) {
                $drivers = collect($date)->groupBy('driver')->toArray();
                $count = 0;
                foreach ($drivers as $name => $driver) {
                    $minDate = searchMin($driver, 'actual_sign_time');
                    $maxDate = searchMax($driver, 'actual_sign_time');
                    $line = implode(',', array_unique(array_column($driver, 'line')));
                    $workHour = number_format((strtotime($maxDate) - strtotime($minDate)) % 86400 / 3600, 1);
                    if ($workHour >= 6 && $workHour < 13) {
                        $sign = 0.5;
                    } elseif ($workHour >= 13) {
                        $sign = 1;
                    } else {
                        $sign = 0;
                    }
                    $postData[$licensePlateNum][$k][$name]['count'] = $sign;
                    $postData[$licensePlateNum][$k][$name]['line'] = $line;
                    $busDriver[$licensePlateNum][] = $name;
                    $busDriver[$licensePlateNum] = array_unique($busDriver[$licensePlateNum]);
                    $count += $sign;
                }
                $postData[$licensePlateNum][$k]['count'] = $count;
            }
        }

        $returnData = [];
        foreach ($busDriver as $licensePlateNum => $drivers) {
            $data = $postData[$licensePlateNum];
            $driverDatas = [];
            foreach ($drivers as $key => $driver) {
                // 先处理合计
                $driverData = [];
                $line = '';
                foreach ($dateList as $k => $date) {
                    $driverItem = $data[$date][$driver] ?? [];
                    $line .= $driverItem ? ','.$driverItem['line'] : '';
                    $driverData[$date] = $driverItem ? $driverItem['count'] : 0;
                }
                $line = substr($line, 1);
                $line = implode(',', array_unique(explode(',', $line)));

                $driverData['working_days'] = array_sum($driverData);
                $driverData['name'] = $driver;
                $driverData['line'] = $line.'路';
                $driverDatas[] = $driverData;
            }
            $sumData = [];
            foreach ($dateList as $k => $date) {
                $sumData[$date] = collect($driverDatas)->sum($date);
            }
            $sumData['working_days'] = array_sum($sumData);
            $sumData['name'] = '陕G'.$licensePlateNum;
            $sumData['line'] = '';

            array_unshift($driverDatas, $sumData);
            $returnData = array_merge($returnData, $driverDatas);
        }

        array_unshift($dateList, 'line');
        array_unshift($dateList, 'name');
        $dateList[] = 'working_days';
        $columns = [];
        foreach ($dateList as $kkk => $vvv) {
            $columns[] = $vvv === 'name' || $vvv === 'line' || $vvv === 'working_days' ? [
                'title' => ($vvv === 'name' ? '姓名' : ($vvv === 'line' ? '线路' : '出勤')),
                'field' => $vvv,
                'align' => $vvv === 'name' ? 'left' : 'center',
                'width' => 80,
                'fixed' => ($vvv === 'name' || $vvv === 'line' ? 'left' : 'right'),
            ] : [
                'title' => date('m-d', strtotime($vvv)),
                'field' => $vvv,
                'align' => 'center',
                'width' => 80,
            ];
        }

        return ['returnData' => $returnData, 'column' => $columns];
    }
}
